package com.swak.loadbalance.impl;

import java.util.List;

import com.swak.exception.DataAccessException;
import com.swak.loadbalance.LoadBalance;
import com.swak.loadbalance.Referer;
import com.swak.loadbalance.WeightAble;
import com.swak.utils.Lists;

public abstract class AbstractLoadBalance<T> implements LoadBalance<T> {

	List<Referer<T>> referers;

	public List<Referer<T>> getReferers() {
		return referers;
	}

	@Override
	public void onRefresh(List<T> referers) {
		List<Referer<T>> refs = Lists.newArrayList(referers.size());
		for (int i = 0; i < referers.size(); i++) {
			T t = referers.get(i);
			refs.add(this.createReferer(t));
		}
		this.referers = refs;
	}

	private Referer<T> createReferer(T t) {
		Referer<T> ref = new Referer<>();
		ref.ref = t;
		if (t instanceof WeightAble) {
			ref.weight = ((WeightAble) t).getWeight();
		}
		return ref;
	}

	@Override
	public T select() {
		List<Referer<T>> referers = this.getReferers();
		if (referers == null) {
			throw new DataAccessException(this.getClass().getSimpleName() + " No available referers:");
		}
		Referer<T> ref = null;
		if (referers.size() > 1) {
			ref = doSelect();
		} else if (referers.size() == 1) {
			ref = referers.get(0);
		}

		if (ref != null) {
			return ref.select();
		}
		return null;
	}

	/**
	 * 选择一个依赖
	 *
	 * @return 依赖
	 */
	protected abstract Referer<T> doSelect();
}